#ifndef __MOD_UDP__
#define __MOD_UDP__

#include "decoder.hpp"

//==========================================================
class UdpSession : public Session
{
public:
};

//==========================================================
class UdpSessionRoot : public SessionRoot
{
public:
  PTree<Session> ssn;
};

//==========================================================
class UdpFilter : public NDecFilter 
{
  friend class UdpDecoder;

private:
  u_int16_t port;
  
  enum FilterType
    {
      FT_SRC_PORT,
      FT_DST_PORT,
    } type;

public:
  UdpFilter (FilterType t) : port (0), type (t) 
  {
    if (this->type == FT_SRC_PORT || this->type == FT_DST_PORT)
      this->setResultType (RT_INT);
  }
  ~UdpFilter () {}

  bool setup (string &arg);
  void check (NDecResult &res);
};

//==========================================================
class UdpMpxFilter : public NDecMpxFilter 
{
public:
  enum FilterType
    {
      FT_NULL = 0,
      FT_SRC_PORT,
      FT_DST_PORT,
    } type;

  UdpMpxFilter (FilterType argType) : type (argType) {}
  ~UdpMpxFilter () {}
  bool setup (string &name, void * p);
  int exec (NDecResult &res);
  void * getResult (int idx);
  
private:
  PTree<NDecMpxRes> portTable;
};

//==========================================================
class UdpRecord : public Record
{
public:
  UdpRecord () : sport (0), dport (0) {} ;
  u_int16_t sport, dport;
};

//==========================================================
class UdpDecoder : public Decoder
{
private:
  static const int SSN_TIMEOUT = 600;
  UdpRecord rec;

public:
  UdpDecoder () {};
  ~UdpDecoder () {};
  
  Record * decode (Packet &pkt, Record &prev);
  UdpSession * fetchUdpSession (Record &prev, u_int16_t &sport, u_int16_t &dport);
  NDecFilter * makeFilter (string &name);
  NDecMpxFilter * makeMpxFilter (string &name);
};

#endif /* __MOD_UDP__ */
